﻿Imports System
Imports System.CodeDom
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.Specialized
Imports System.Globalization
Imports System.IO
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Text

Namespace System.Workflow.ComponentModel.Compiler
    Public NotInheritable Class TypeProvider
        Implements ITypeProvider, IServiceProvider, IDisposable
        ' Events
        Public Custom Event TypeLoadErrorsChanged As EventHandler
        Public Custom Event TypesChanged As EventHandler

        ' Methods
        Public Sub New(ByVal serviceProvider As IServiceProvider)
            Me.serviceProvider = serviceProvider
        End Sub

        Public Sub AddAssembly(ByVal [assembly] As Assembly)
            If ([assembly] Is Nothing) Then
                Throw New ArgumentNullException("assembly")
            End If
            If Not Me.rawAssemblyLoaders.Contains([assembly]) Then
                Try 
                    Me.rawAssemblyLoaders.Item([assembly]) = New AssemblyLoader(Me, [assembly], (Me.localAssembly Is [assembly]))
                    If (Not Me.TypesChanged Is Nothing) Then
                        TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
                    End If
                Catch exception As Exception
                    Me.typeLoadErrors.Item([assembly].FullName) = exception
                    If (Not Me.TypeLoadErrorsChanged Is Nothing) Then
                        TypeProvider.FireEventsNoThrow(Me.TypeLoadErrorsChanged, New Object() { Me, EventArgs.Empty })
                    End If
                End Try
            End If
        End Sub

        Public Sub AddAssemblyReference(ByVal path As String)
            If (path Is Nothing) Then
                Throw New ArgumentNullException("path")
            End If
            If ((File.Exists(path) AndAlso Not Me.assemblyLoaders.ContainsKey(path)) AndAlso ((Me.addedAssemblies Is Nothing) OrElse Not Me.addedAssemblies.Contains(path))) Then
                If (Me.addedAssemblies Is Nothing) Then
                    Me.addedAssemblies = New List([Of] String)
                End If
                Me.addedAssemblies.Add(path)
                If (Not Me.TypesChanged Is Nothing) Then
                    TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
                End If
            End If
        End Sub

        Public Sub AddCodeCompileUnit(ByVal codeCompileUnit As CodeCompileUnit)
            If (codeCompileUnit Is Nothing) Then
                Throw New ArgumentNullException("codeCompileUnit")
            End If
            If (Me.compileUnitLoaders.ContainsKey(codeCompileUnit) OrElse ((Not Me.addedCompileUnits Is Nothing) AndAlso Me.addedCompileUnits.Contains(codeCompileUnit))) Then
                Throw New ArgumentException(TypeSystemSR.GetString("Error_DuplicateCodeCompileUnit"), "codeCompileUnit")
            End If
            If (Me.addedCompileUnits Is Nothing) Then
                Me.addedCompileUnits = New List([Of] CodeCompileUnit)
            End If
            Me.addedCompileUnits.Add(codeCompileUnit)
            If ((Not Me.needRefreshCompileUnits Is Nothing) AndAlso Me.needRefreshCompileUnits.ContainsKey(codeCompileUnit)) Then
                Me.needRefreshCompileUnits.Remove(codeCompileUnit)
            End If
            If (Not Me.TypesChanged Is Nothing) Then
                TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
            End If
        End Sub

        Friend Sub AddType(ByVal type As Type)
            Dim fullName As String = type.FullName
            If Not Me.designTimeTypes.Contains(fullName) Then
                Me.designTimeTypes.Item(fullName) = type
            End If
        End Sub

        Public Sub Dispose()
            If (Not Me.compileUnitLoaders Is Nothing) Then
                Dim loader As CodeDomLoader
                For Each loader In Me.compileUnitLoaders.Values
                    loader.Dispose
                Next
                Me.compileUnitLoaders.Clear
            End If
            Me.addedAssemblies = Nothing
            Me.addedCompileUnits = Nothing
            Me.needRefreshCompileUnits = Nothing
        End Sub

        Private Sub EnsureCurrentTypes()
            If Not Me.executingEnsureCurrentTypes Then
                Try 
                    Dim flag As Boolean = False
                    Me.executingEnsureCurrentTypes = True
                    If (Not Me.addedAssemblies Is Nothing) Then
                        Dim strArray As String() = Me.addedAssemblies.ToArray
                        Me.addedAssemblies = Nothing
                        Dim str As String
                        For Each str In strArray
                            Dim loader As AssemblyLoader = Nothing
                            Try 
                                loader = New AssemblyLoader(Me, str)
                                Me.assemblyLoaders.Item(str) = loader
                            Catch exception As Exception
                                Me.typeLoadErrors.Item(str) = exception
                                flag = True
                            End Try
                        Next
                    End If
                    If (Not Me.addedCompileUnits Is Nothing) Then
                        Dim unitArray As CodeCompileUnit() = Me.addedCompileUnits.ToArray
                        Me.addedCompileUnits = Nothing
                        Dim unit As CodeCompileUnit
                        For Each unit In unitArray
                            Dim loader2 As CodeDomLoader = Nothing
                            Try 
                                loader2 = New CodeDomLoader(Me, unit)
                                Me.compileUnitLoaders.Item(unit) = loader2
                            Catch exception2 As Exception
                                If (Not loader2 Is Nothing) Then
                                    loader2.Dispose
                                End If
                                Me.typeLoadErrors.Item(unit) = exception2
                                flag = True
                            End Try
                        Next
                    End If
                    If (Not Me.needRefreshCompileUnits Is Nothing) Then
                        Dim dictionary As New Dictionary([Of] CodeCompileUnit, EventHandler)
                        Dim pair As KeyValuePair([Of] CodeCompileUnit, EventHandler)
                        For Each pair In Me.needRefreshCompileUnits
                            dictionary.Add(pair.Key, pair.Value)
                        Next
                        Me.needRefreshCompileUnits = Nothing
                        Dim pair2 As KeyValuePair([Of] CodeCompileUnit, EventHandler)
                        For Each pair2 In dictionary
                            Dim loader3 As CodeDomLoader = [TryCast](Me.compileUnitLoaders.Item(pair2.Key),CodeDomLoader)
                            If (Not loader3 Is Nothing) Then
                                Try 
                                    loader3.Refresh(pair2.Value)
                                    [Continue] For
                                Catch exception3 As Exception
                                    Me.typeLoadErrors.Item(pair2.Value) = exception3
                                    flag = True
                                    [Continue] For
                                End Try
                            End If
                        Next
                    End If
                    If (flag AndAlso (Not Me.TypeLoadErrorsChanged Is Nothing)) Then
                        TypeProvider.FireEventsNoThrow(Me.TypeLoadErrorsChanged, New Object() { Me, EventArgs.Empty })
                    End If
                Finally
                    Me.executingEnsureCurrentTypes = False
                End Try
            End If
        End Sub

        Private Shared Sub FireEventsNoThrow(ByVal eventDelegator As Delegate, ByVal args As Object())
            If (Not eventDelegator Is Nothing) Then
                Dim delegate2 As Delegate
                For Each delegate2 In eventDelegator.GetInvocationList
                    Try 
                        delegate2.DynamicInvoke(args)
                    Catch exception1 As Exception
                    End Try
                Next
            End If
        End Sub

        Public Shared Function GetEnumNames(ByVal enumType As Type) As String()
            If (enumType Is Nothing) Then
                Throw New ArgumentNullException("enumType")
            End If
            If Not TypeProvider.IsSubclassOf(enumType, GetType(Enum)) Then
                Throw New ArgumentException(TypeSystemSR.GetString("Error_TypeIsNotEnum"))
            End If
            Dim fields As FieldInfo() = enumType.GetFields
            Dim list As New List([Of] String)
            Dim i As Integer
            For i = 0 To fields.Length - 1
                list.Add(fields(i).Name)
            Next i
            list.Sort
            Return list.ToArray
        End Function

        Public Shared Function GetEventHandlerType(ByVal eventInfo As EventInfo) As Type
            If (eventInfo Is Nothing) Then
                Throw New ArgumentNullException("eventInfo")
            End If
            Dim addMethod As MethodInfo = eventInfo.GetAddMethod(True)
            If (Not addMethod Is Nothing) Then
                Dim parameters As ParameterInfo() = addMethod.GetParameters
                Dim superClass As Type = GetType(Delegate)
                Dim i As Integer
                For i = 0 To parameters.Length - 1
                    Dim parameterType As Type = parameters(i).ParameterType
                    If TypeProvider.IsSubclassOf(parameterType, superClass) Then
                        Return parameterType
                    End If
                Next i
            End If
            Return Nothing
        End Function

        Public Function GetService(ByVal serviceType As Type) As Object
            If (Me.serviceProvider Is Nothing) Then
                Return Nothing
            End If
            Return Me.serviceProvider.GetService(serviceType)
        End Function

        Public Function [GetType](ByVal name As String) As Type
            If (name Is Nothing) Then
                Throw New ArgumentNullException("name")
            End If
            Return Me.GetType(name, False)
        End Function

        Public Function [GetType](ByVal name As String, ByVal throwOnError As Boolean) As Type
            If (name Is Nothing) Then
                Throw New ArgumentNullException("name")
            End If
            Me.EnsureCurrentTypes
            Dim flag As Boolean = False
            Dim type As Type = Nothing
            Dim typeName As String = String.Empty
            Dim parameters As String() = Nothing
            Dim elemantDecorator As String = String.Empty
            If ParseHelpers.ParseTypeName(name, ParseTypeNameLanguage.NetFramework, typeName, parameters, elemantDecorator) Then
                If ((Not parameters Is Nothing) AndAlso (parameters.Length > 0)) Then
                    Dim type2 As Type = Me.GetType(typeName, throwOnError)
                    If ((type2 Is Nothing) OrElse Not type2.IsGenericTypeDefinition) Then
                        Return Nothing
                    End If
                    Dim typeArguments As Type() = New Type(parameters.Length  - 1) {}
                    Dim i As Integer
                    For i = 0 To parameters.Length - 1
                        Dim type3 As Type = Me.GetType(parameters(i), throwOnError)
                        If (type3 Is Nothing) Then
                            Return Nothing
                        End If
                        typeArguments(i) = type3
                    Next i
                    Return type2.MakeGenericType(typeArguments)
                End If
                If (elemantDecorator <> String.Empty) Then
                    Dim type4 As Type = Me.GetType(typeName)
                    If (Not type4 Is Nothing) Then
                        Dim builder As New StringBuilder(type4.FullName)
                        Dim j As Integer
                        For j = 0 To elemantDecorator.Length - 1
                            If (elemantDecorator.Chars(j) <> " "c) Then
                                builder.Append(elemantDecorator.Chars(j))
                            End If
                        Next j
                        name = builder.ToString
                        If (Not type4.Assembly Is Nothing) Then
                            type = type4.Assembly.GetType(name, False)
                        End If
                        If (type Is Nothing) Then
                            If Me.hashOfDTTypes.Contains(name) Then
                                Return [TryCast](Me.hashOfDTTypes.Item(name),Type)
                            End If
                            type = New DesignTimeType(Nothing, name, Me)
                            Me.hashOfDTTypes.Add(name, type)
                            Return type
                        End If
                    End If
                Else
                    Dim thatName As String = String.Empty
                    Dim index As Integer = name.IndexOf(","c)
                    If (index <> -1) Then
                        typeName = name.Substring(0, index)
                        thatName = name.Substring((index + 1)).Trim
                    End If
                    typeName = typeName.Trim
                    If (typeName.Length > 0) Then
                        type = [TryCast](Me.designTimeTypes.Item(typeName),Type)
                        If (type Is Nothing) Then
                            Dim entry As DictionaryEntry
                            For Each entry In Me.rawAssemblyLoaders
                                Dim loader As AssemblyLoader = [TryCast](entry.Value,AssemblyLoader)
                                If ((thatName.Length = 0) OrElse ParseHelpers.AssemblyNameEquals(loader.AssemblyName, thatName)) Then
                                    Try 
                                        type = loader.GetType(typeName)
                                    Catch exception As Exception
                                        If Not Me.typeLoadErrors.Contains(entry.Key) Then
                                            Me.typeLoadErrors.Item(entry.Key) = exception
                                            flag = True
                                        End If
                                        If throwOnError Then
                                            Throw exception
                                        End If
                                    End Try
                                    If (Not type Is Nothing) Then
                                        Exit For
                                    End If
                                End If
                            Next
                        End If
                        If (type Is Nothing) Then
                            Dim entry2 As DictionaryEntry
                            For Each entry2 In Me.assemblyLoaders
                                Dim loader2 As AssemblyLoader = [TryCast](entry2.Value,AssemblyLoader)
                                If ((thatName.Length = 0) OrElse ParseHelpers.AssemblyNameEquals(loader2.AssemblyName, thatName)) Then
                                    Try 
                                        type = loader2.GetType(typeName)
                                    Catch exception2 As Exception
                                        If Not Me.typeLoadErrors.Contains(entry2.Key) Then
                                            Me.typeLoadErrors.Item(entry2.Key) = exception2
                                            flag = True
                                        End If
                                        If throwOnError Then
                                            Throw exception2
                                        End If
                                    End Try
                                    If (Not type Is Nothing) Then
                                        Exit For
                                    End If
                                End If
                            Next
                        End If
                        If (flag AndAlso (Not Me.TypeLoadErrorsChanged Is Nothing)) Then
                            TypeProvider.FireEventsNoThrow(Me.TypeLoadErrorsChanged, New Object() { Me, EventArgs.Empty })
                        End If
                        If (((type Is Nothing) AndAlso (Not Me.localAssembly Is Nothing)) AndAlso (thatName = Me.localAssembly.FullName)) Then
                            type = Me.localAssembly.GetType(typeName)
                        End If
                    End If
                End If
            End If
            If (type Is Nothing) Then
                If throwOnError Then
                    Throw New Exception(TypeSystemSR.GetString(CultureInfo.CurrentCulture, "Error_TypeResolution", New Object() { name }))
                End If
                Return Nothing
            End If
            If (((Me.designTimeTypes Is Nothing) OrElse (Me.designTimeTypes.Count <= 0)) OrElse ((type.Assembly Is Nothing) OrElse Not type.IsGenericTypeDefinition)) Then
                Return type
            End If
            If Me.hashOfRTTypes.Contains(type) Then
                Return DirectCast(Me.hashOfRTTypes.Item(type), Type)
            End If
            Dim type5 As Type = New RTTypeWrapper(Me, type)
            Me.hashOfRTTypes.Add(type, type5)
            Return type5
        End Function

        Public Function GetTypes() As Type()
            Me.EnsureCurrentTypes
            Dim flag As Boolean = False
            Me.typeLoadErrors.Clear
            Dim list As New List([Of] Type)
            Dim type As Type
            For Each type In Me.designTimeTypes.Values
                list.Add(type)
            Next
            Dim entry As DictionaryEntry
            For Each entry In Me.assemblyLoaders
                Dim loader As AssemblyLoader = [TryCast](entry.Value,AssemblyLoader)
                Try 
                    list.AddRange(loader.GetTypes)
                    [Continue] For
                Catch exception As Exception
                    Dim exception2 As ReflectionTypeLoadException = [TryCast](exception,ReflectionTypeLoadException)
                    If (Not exception2 Is Nothing) Then
                        Dim type2 As Type
                        For Each type2 In exception2.Types
                            If (Not type2 Is Nothing) Then
                                list.Add(type2)
                            End If
                        Next
                    End If
                    If Me.typeLoadErrors.Contains(entry.Key) Then
                        Me.typeLoadErrors.Remove(entry.Key)
                    End If
                    Me.typeLoadErrors.Item(entry.Key) = exception
                    flag = True
                    [Continue] For
                End Try
            Next
            Dim entry2 As DictionaryEntry
            For Each entry2 In Me.rawAssemblyLoaders
                Dim loader2 As AssemblyLoader = [TryCast](entry2.Value,AssemblyLoader)
                Try 
                    list.AddRange(loader2.GetTypes)
                    [Continue] For
                Catch exception3 As Exception
                    Dim exception4 As ReflectionTypeLoadException = [TryCast](exception3,ReflectionTypeLoadException)
                    If (Not exception4 Is Nothing) Then
                        Dim type3 As Type
                        For Each type3 In exception4.Types
                            If (Not type3 Is Nothing) Then
                                list.Add(type3)
                            End If
                        Next
                    End If
                    If Me.typeLoadErrors.Contains(entry2.Key) Then
                        Me.typeLoadErrors.Remove(entry2.Key)
                    End If
                    Me.typeLoadErrors.Item(entry2.Key) = exception3
                    flag = True
                    [Continue] For
                End Try
            Next
            If (flag AndAlso (Not Me.TypeLoadErrorsChanged Is Nothing)) Then
                TypeProvider.FireEventsNoThrow(Me.TypeLoadErrorsChanged, New Object() { Me, EventArgs.Empty })
            End If
            Return list.ToArray
        End Function

        Public Shared Function IsAssignable(ByVal toType As Type, ByVal fromType As Type) As Boolean
            Return TypeProvider.IsAssignable(toType, fromType, False)
        End Function

        Friend Shared Function IsAssignable(ByVal toType As Type, ByVal fromType As Type, ByVal equalBasedOnSameTypeRepresenting As Boolean) As Boolean
            If ((toType Is Nothing) OrElse (fromType Is Nothing)) Then
                Return False
            End If
            If equalBasedOnSameTypeRepresenting Then
                If TypeProvider.IsRepresentingTheSameType(fromType, toType) Then
                    Return True
                End If
            ElseIf (fromType Is toType) Then
                Return True
            End If
            If Not toType.IsGenericTypeDefinition Then
                If ((toType.Assembly Is Nothing) AndAlso (Not fromType.Assembly Is Nothing)) Then
                    Return False
                End If
                If (TypeOf fromType Is RTTypeWrapper OrElse TypeOf fromType Is DesignTimeType) Then
                    If (Not TypeOf toType Is RTTypeWrapper AndAlso Not TypeOf toType Is DesignTimeType) Then
                        Dim provider As ITypeProvider = If(TypeOf fromType Is RTTypeWrapper, [TryCast](fromType,RTTypeWrapper).Provider, [TryCast](fromType,DesignTimeType).Provider)
                        If (Not provider Is Nothing) Then
                            toType = provider.GetType(toType.FullName)
                        End If
                    End If
                    goto Label_00F4
                End If
                If (TypeOf toType Is RTTypeWrapper OrElse TypeOf toType Is DesignTimeType) Then
                    If (Not TypeOf fromType Is RTTypeWrapper AndAlso Not TypeOf fromType Is DesignTimeType) Then
                        Dim provider2 As ITypeProvider = If(TypeOf toType Is RTTypeWrapper, [TryCast](toType,RTTypeWrapper).Provider, [TryCast](toType,DesignTimeType).Provider)
                        If (Not provider2 Is Nothing) Then
                            fromType = provider2.GetType(fromType.FullName)
                        End If
                    End If
                    goto Label_00F4
                End If
            End If
            Return toType.IsAssignableFrom(fromType)
        Label_00F4:
            If ((Not toType Is Nothing) AndAlso (Not fromType Is Nothing)) Then
                If equalBasedOnSameTypeRepresenting Then
                    If TypeProvider.IsRepresentingTheSameType(fromType, toType) Then
                        Return True
                    End If
                ElseIf (fromType Is toType) Then
                    Return True
                End If
                If TypeProvider.IsSubclassOf(fromType, toType) Then
                    Return True
                End If
                If toType.IsInterface Then
                    Dim interfaces As Type() = fromType.GetInterfaces
                    Dim i As Integer
                    For i = 0 To interfaces.Length - 1
                        If (interfaces(i) Is toType) Then
                            Return True
                        End If
                        If TypeProvider.IsSubclassOf(interfaces(i), toType) Then
                            Return True
                        End If
                    Next i
                End If
            End If
            Return False
        End Function

        Public Shared Function IsEnum(ByVal type As Type) As Boolean
            If (type Is Nothing) Then
                Throw New ArgumentNullException("type")
            End If
            Return TypeProvider.IsSubclassOf(type, GetType(Enum))
        End Function

        Friend Shared Function IsRepresentingTheSameType(ByVal firstType As Type, ByVal secondType As Type) As Boolean
            If ((firstType Is Nothing) OrElse (secondType Is Nothing)) Then
                Return False
            End If
            If (Not firstType Is secondType) Then
                If (firstType.FullName <> secondType.FullName) Then
                    Return False
                End If
                If (Not firstType.Assembly Is secondType.Assembly) Then
                    Return False
                End If
                If ((Not firstType.Assembly Is Nothing) AndAlso (firstType.AssemblyQualifiedName <> secondType.AssemblyQualifiedName)) Then
                    Return False
                End If
            End If
            Return True
        End Function

        Public Shared Function IsSubclassOf(ByVal subclass As Type, ByVal superClass As Type) As Boolean
            If (Not superClass Is subclass) Then
                If ((subclass Is Nothing) OrElse (superClass Is Nothing)) Then
                    Return False
                End If
                If (superClass Is GetType(Object)) Then
                    Return True
                End If
                subclass = subclass.BaseType
                Do While (Not subclass Is Nothing)
                    If (superClass Is subclass) Then
                        Return True
                    End If
                    subclass = subclass.BaseType
                Loop
            End If
            Return False
        End Function

        Public Sub RefreshCodeCompileUnit(ByVal codeCompileUnit As CodeCompileUnit, ByVal refresher As EventHandler)
            If (codeCompileUnit Is Nothing) Then
                Throw New ArgumentNullException("codeCompileUnit")
            End If
            If ((Not Me.compileUnitLoaders.Contains(codeCompileUnit) AndAlso (Not Me.addedCompileUnits Is Nothing)) AndAlso Not Me.addedCompileUnits.Contains(codeCompileUnit)) Then
                Throw New ArgumentException(TypeSystemSR.GetString("Error_NoCodeCompileUnit"), "codeCompileUnit")
            End If
            If (Me.needRefreshCompileUnits Is Nothing) Then
                Me.needRefreshCompileUnits = New Dictionary([Of] CodeCompileUnit, EventHandler)
            End If
            Me.needRefreshCompileUnits.Item(codeCompileUnit) = refresher
            If (Not Me.TypesChanged Is Nothing) Then
                TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
            End If
        End Sub

        Public Sub RemoveAssembly(ByVal [assembly] As Assembly)
            If ([assembly] Is Nothing) Then
                Throw New ArgumentNullException("assembly")
            End If
            If (Not DirectCast(Me.rawAssemblyLoaders.Item([assembly]), AssemblyLoader) Is Nothing) Then
                Me.rawAssemblyLoaders.Remove([assembly])
                Me.RemoveCachedAssemblyWrappedTypes([assembly])
                If (Not Me.TypesChanged Is Nothing) Then
                    TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
                End If
            End If
        End Sub

        Public Sub RemoveAssemblyReference(ByVal path As String)
            If (path Is Nothing) Then
                Throw New ArgumentNullException("path")
            End If
            Dim loader As AssemblyLoader = [TryCast](Me.assemblyLoaders.Item(path),AssemblyLoader)
            If (Not loader Is Nothing) Then
                Me.assemblyLoaders.Remove(path)
                Me.RemoveCachedAssemblyWrappedTypes(loader.Assembly)
            End If
            If ((Not Me.addedAssemblies Is Nothing) AndAlso Me.addedAssemblies.Contains(path)) Then
                Me.addedAssemblies.Remove(path)
            End If
            If Me.typeLoadErrors.ContainsKey(path) Then
                Me.typeLoadErrors.Remove(path)
                If (Not Me.TypeLoadErrorsChanged Is Nothing) Then
                    TypeProvider.FireEventsNoThrow(Me.TypeLoadErrorsChanged, New Object() { Me, EventArgs.Empty })
                End If
            End If
            If (Not Me.TypesChanged Is Nothing) Then
                TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
            End If
        End Sub

        Private Sub RemoveCachedAssemblyWrappedTypes(ByVal [assembly] As Assembly)
            Dim list As New ArrayList(Me.hashOfRTTypes.Keys)
            Dim type As Type
            For Each type In list
                If type.IsGenericTypeDefinition Then
                    DirectCast(Me.hashOfRTTypes.Item(type), RTTypeWrapper).OnAssemblyRemoved([assembly])
                End If
                If (type.Assembly Is [assembly]) Then
                    Me.hashOfRTTypes.Remove(type)
                End If
            Next
        End Sub

        Public Sub RemoveCodeCompileUnit(ByVal codeCompileUnit As CodeCompileUnit)
            If (codeCompileUnit Is Nothing) Then
                Throw New ArgumentNullException("codeCompileUnit")
            End If
            Dim loader As CodeDomLoader = [TryCast](Me.compileUnitLoaders.Item(codeCompileUnit),CodeDomLoader)
            If (Not loader Is Nothing) Then
                loader.Dispose
                Me.compileUnitLoaders.Remove(codeCompileUnit)
            End If
            If ((Not Me.addedCompileUnits Is Nothing) AndAlso Me.addedCompileUnits.Contains(codeCompileUnit)) Then
                Me.addedCompileUnits.Remove(codeCompileUnit)
            End If
            If ((Not Me.needRefreshCompileUnits Is Nothing) AndAlso Me.needRefreshCompileUnits.ContainsKey(codeCompileUnit)) Then
                Me.needRefreshCompileUnits.Remove(codeCompileUnit)
            End If
            If Me.typeLoadErrors.ContainsKey(codeCompileUnit) Then
                Me.typeLoadErrors.Remove(codeCompileUnit)
                If (Not Me.TypeLoadErrorsChanged Is Nothing) Then
                    TypeProvider.FireEventsNoThrow(Me.TypeLoadErrorsChanged, New Object() { Me, EventArgs.Empty })
                End If
            End If
            If (Not Me.TypesChanged Is Nothing) Then
                TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
            End If
        End Sub

        Friend Sub RemoveTypes(ByVal types As Type())
            Dim type As Type
            For Each type In types
                Dim fullName As String = type.FullName
                Dim strings As New StringCollection
                Dim type2 As Type
                For Each type2 In Me.hashOfDTTypes.Values
                    Dim elementType As Type = type2
                    Do While ((Not elementType Is Nothing) AndAlso elementType.HasElementType)
                        elementType = elementType.GetElementType
                    Loop
                    If (elementType Is type) Then
                        strings.Add(type2.FullName)
                    End If
                Next
                Dim str2 As String
                For Each str2 In strings
                    Me.hashOfDTTypes.Remove(str2)
                Next
                Me.designTimeTypes.Remove(fullName)
            Next
        End Sub

        Public Sub SetLocalAssembly(ByVal [assembly] As Assembly)
            Me.localAssembly = [assembly]
            If (Not Me.TypesChanged Is Nothing) Then
                TypeProvider.FireEventsNoThrow(Me.TypesChanged, New Object() { Me, EventArgs.Empty })
            End If
        End Sub


        ' Properties
        Public ReadOnly Property LocalAssembly As Assembly
            Get
                Return Me.localAssembly
            End Get
        End Property

        Public ReadOnly Property ReferencedAssemblies As ICollection([Of] Assembly)
            Get
                Me.EnsureCurrentTypes
                Dim list As New List([Of] Assembly)
                Dim loader As AssemblyLoader
                For Each loader In Me.assemblyLoaders.Values
                    If (Not loader.Assembly Is Nothing) Then
                        list.Add(loader.Assembly)
                    End If
                Next
                Dim assembly As Assembly
                For Each assembly In Me.rawAssemblyLoaders.Keys
                    list.Add([assembly])
                Next
                Return list.AsReadOnly
            End Get
        End Property

        Public ReadOnly Property TypeLoadErrors As IDictionary([Of] Object, Exception)
            Get
                Dim dictionary As New Dictionary([Of] Object, Exception)
                Dim entry As DictionaryEntry
                For Each entry In Me.typeLoadErrors
                    Dim innerException As Exception = [TryCast](entry.Value,Exception)
                    Do While TypeOf innerException Is TargetInvocationException
                        innerException = innerException.InnerException
                    Loop
                    If (Not innerException Is Nothing) Then
                        Dim message As String = Nothing
                        If TypeOf entry.Key Is CodeCompileUnit Then
                            message = TypeSystemSR.GetString("Error_CodeCompileUnitNotLoaded", New Object() { innerException.Message })
                        ElseIf TypeOf entry.Key Is String Then
                            message = TypeSystemSR.GetString("Error_AssemblyRefNotLoaded", New Object() { entry.Key.ToString, innerException.Message })
                        End If
                        If (Not message Is Nothing) Then
                            innerException = New Exception(message, innerException)
                        End If
                        dictionary.Add(entry.Key, innerException)
                    End If
                Next
                Return dictionary
            End Get
        End Property


        ' Fields
        Private addedAssemblies As List([Of] String)
        Private addedCompileUnits As List([Of] CodeCompileUnit)
        Private assemblyLoaders As Hashtable = New Hashtable
        Private compileUnitLoaders As Hashtable = New Hashtable
        Private designTimeTypes As Hashtable = New Hashtable
        Private executingEnsureCurrentTypes As Boolean
        Private hashOfDTTypes As Hashtable = New Hashtable
        Private hashOfRTTypes As Hashtable = New Hashtable
        Private localAssembly As Assembly
        Friend Shared ReadOnly nameSeparators As Char() = New Char() { "."c, "+"c }
        Private needRefreshCompileUnits As Dictionary([Of] CodeCompileUnit, EventHandler)
        Private rawAssemblyLoaders As Hashtable = New Hashtable
        Private serviceProvider As IServiceProvider
        Private typeLoadErrors As Hashtable = New Hashtable
    End Class
End Namespace

